package team.knowers.tourist.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.knowers.tourist.common.convention.exception.ClientException;
import team.knowers.tourist.dao.entity.BookingDO;
import team.knowers.tourist.dao.entity.FlightDO;
import team.knowers.tourist.dao.entity.PaymentDO;
import team.knowers.tourist.dao.mapper.BookingMapper;
import team.knowers.tourist.dto.req.BookingCreateReqDTO;
import team.knowers.tourist.dto.req.PaymentCreateReqDTO;
import team.knowers.tourist.service.BookingService;
import team.knowers.tourist.service.FlightService;
import team.knowers.tourist.service.NoticeService;
import team.knowers.tourist.service.PaymentService;

import java.util.List;
import java.util.Random;

@Service
@RequiredArgsConstructor
public class BookingServiceImpl extends ServiceImpl<BookingMapper, BookingDO> implements BookingService {
    private final FlightService flightService;
    private final NoticeService noticeService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer createBooking(BookingCreateReqDTO req) {
        LambdaQueryWrapper<BookingDO> wrapper= Wrappers.lambdaQuery(BookingDO.class)
                .eq(BookingDO::getTouristId,req.getTouristId())
                .eq(BookingDO::getFlightId,req.getFlightId())
                .eq(BookingDO::getDelFlag,0);
        BookingDO bookingDO=baseMapper.selectOne(wrapper);
        FlightDO flightDO=flightService.getFlight(req.getFlightId());
        if(!isVacancy(flightDO,req.getSeatReq()))
        {
            throw new ClientException("该航班机票已售罄");
        }
        if(bookingDO!=null)
        {
            throw new ClientException("已预订");
        }
        int a=generateRandomNumber(0,1000000000);
        BookingDO bookingDO1=BookingDO.builder()
                .touristId(req.getTouristId())
                .flightId(req.getFlightId())
                .seatReq(req.getSeatReq())
                .bookingHash(a)
                .flightNo(flightDO.getFlightNo())
                .startTime(flightDO.getStartTime())
                .endTime(flightDO.getEndTime())
                .startPlace(flightDO.getStartPlace())
                .endPlace(flightDO.getEndPlace())
                .bookingAmount(req.getAmount())
                .build();
        baseMapper.insert(bookingDO1);
        PaymentDO paymentDO= PaymentDO.builder()
                .flightId(req.getFlightId())
                .identifyNumber(req.getIdentifyNumber())
                .amount(req.getAmount())
                .build();
        flightService.modifyInformation(flightDO.getId(),-1,req.getSeatReq());
        noticeService.addNoticeWhenBooking(req,a);
        return a;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelBooking(int bookingId) {
        LambdaQueryWrapper<BookingDO> wrapper= Wrappers.lambdaQuery(BookingDO.class)
                .eq(BookingDO::getId,bookingId)
                .eq(BookingDO::getDelFlag,0);
        BookingDO bookingDO=baseMapper.selectOne(wrapper);
        if(bookingDO==null)
        {
            throw new ClientException("所取消的订单不存在");
        }
        bookingDO.setDelFlag(1);
        baseMapper.updateById(bookingDO);
        FlightDO flightDO=flightService.getFlight(bookingDO.getFlightId());
        flightService.modifyInformation(flightDO.getId(),1,bookingDO.getSeatReq());


    }

    @Override
    public List<BookingDO> viewBooking(int touristId) {
        LambdaQueryWrapper<BookingDO> wrapper=Wrappers.lambdaQuery(BookingDO.class)
                .eq(BookingDO::getTouristId,touristId)
                .orderByDesc(BookingDO::getCreateTime)
                .eq(BookingDO::getDelFlag,0);
        return baseMapper.selectList(wrapper);
    }

    @Override
    public BookingDO findBooking(int booking) {
        LambdaQueryWrapper<BookingDO> wrapper=Wrappers.lambdaQuery(BookingDO.class)
                .eq(BookingDO::getId,booking)
                .eq(BookingDO::getDelFlag,0);
        BookingDO bookingDO=baseMapper.selectOne(wrapper);
        return bookingDO;
    }

    /**
     * 生成随机数
     */
    public static int generateRandomNumber(int min, int max) {
        Random random = new Random();
        return random.nextInt(max - min + 1) + min;

    }
    /**
     * 判断是否有空位
     */
    public static boolean isVacancy(FlightDO flightDO,Integer seatReq)
    {
        if(seatReq==0)
        {
            if(flightDO.getNowEcoSeats()==0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            if(flightDO.getNowHeadSeats()==0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}
